package com.ysd.twocrm.config;

import com.ysd.twocrm.shiro.UserRealm;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

import javax.servlet.Filter;
import javax.servlet.http.HttpSession;
import java.util.*;

/**
 * shiro配置类
 * Qualifier:找下面的bean里面的name
 */
@Configuration
public class ShiroConfig {


    /*
     * @Description AOP认证，这个idea开发工具不加这个的话无法访问shiro授权的方法
     * @param
     * @return org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator
     * @author liusupeng
     * @date 2020/5/8 21:50
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {

        DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        autoProxyCreator.setProxyTargetClass(true);
        return autoProxyCreator;
    }



    /**
     * 解决setUnauthorizedUrl不能跳转的问题
     * 使用注册设置权限
     * */
       @Bean
        public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
           AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
           authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
           return authorizationAttributeSourceAdvisor;
      }







@Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(){
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager());      //加载核心控制器

           //如果没登录就跳转到页面登录
    shiroFilterFactoryBean.setLoginUrl("/users/getgologin");
    //登录后没权限跳转的接口
    shiroFilterFactoryBean.setUnauthorizedUrl("/users/permissionLogOut");
      //配置访问权限链
    LinkedHashMap<String,String> filterMap=new LinkedHashMap<String,String>();

    filterMap.put("/users/**","anon");
    filterMap.put("/aliyun/getSsm","anon");
    filterMap.put("/logs/**","anon");
    filterMap.put("/websocket/**","anon");
    filterMap.put("/websocketverify/**","anon");
    filterMap.put("/**","authc");
    filterMap.put("/**","user");//放行记住我
    shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);//将权限链加入到过滤器

        /**
         * 添加内置过滤器
         * 常用的过滤器：anon：无需认证就可访问
         * authc:必须认证才能访问
         * user:如果使用rememberme的功能访问
         * perms：该资源必须得到资源权限才可以访问
         * role：该资源必须得到角色权限才可以访问
         */

      return shiroFilterFactoryBean;
    }
    //核心控制器
    @Bean
public SecurityManager securityManager(){
        DefaultWebSecurityManager webSecurityManager=new DefaultWebSecurityManager();
    webSecurityManager.setRealm(getRealm());
    webSecurityManager.setRememberMeManager(rememberMeMeManager());

    return webSecurityManager;
}

@Bean
    public UserRealm getRealm(){
    //配置自定义的realm
        return new UserRealm();
    }
    /**
     * 解决： 无权限页面不跳转 shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized") 无效
     * shiro的源代码ShiroFilterFactoryBean.Java定义的filter必须满足filter instanceof AuthorizationFilter，
     * 只有perms，roles，ssl，rest，port才是属于AuthorizationFilter，而anon，authcBasic，auchc，user是AuthenticationFilter，
     * 所以unauthorizedUrl设置后页面不跳转 Shiro注解模式下，登录失败与没有权限都是通过抛出异常。
     * 并且默认并没有去处理或者捕获这些异常。在SpringMVC下需要配置捕获相应异常来通知用户信息
     * @return
     */
    @Bean
    public SimpleMappingExceptionResolver simpleMappingExceptionResolver() {
        SimpleMappingExceptionResolver simpleMappingExceptionResolver=new SimpleMappingExceptionResolver();
        Properties properties=new Properties();
        properties.setProperty("org.apache.shiro.authz.UnauthorizedException","/users/permissionLogOut");
        properties.setProperty("org.apache.shiro.authz.UnauthenticatedException","/users/permissionLogOut");
        simpleMappingExceptionResolver.setExceptionMappings(properties);
        return simpleMappingExceptionResolver;
    }

    //设置cookie的时间
    @Bean
    public SimpleCookie rememberMeCookie(){

        SimpleCookie simpleCookie=new SimpleCookie("rememberMe");
        simpleCookie.setMaxAge(3600);//一小时
        return simpleCookie;
    }
    //rememberMe管理器
@Bean
    public CookieRememberMeManager rememberMeMeManager(){
        CookieRememberMeManager cookieRememberMeManager=new CookieRememberMeManager();
        cookieRememberMeManager.setCookie(rememberMeCookie());
        //加密
        cookieRememberMeManager.setCipherKey(Base64.decode("2AvVhdsgUsOFSA3SDFAdag=="));
        return cookieRememberMeManager;
    }

}
